package com.tobby.camel.camelinaction.chapter5.errorhandler;

import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.JndiRegistry;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

public class SyncVSASyncDelayedRedeliveryTest extends CamelTestSupport {

	@Override
	protected JndiRegistry createRegistry() throws Exception {
		JndiRegistry jndi = super.createRegistry();
		jndi.bind("orderService", new OrderService());
		return jndi;
	}

	@Override
	public boolean isUseRouteBuilder() {
		return false;
	}

	@Test
	public void testSyncOrderFailThenOK() throws Exception {
		context.addRoutes(new RouteBuilder() {

			@Override
			public void configure() throws Exception {
				errorHandler(deadLetterChannel("mock:dead").maximumRedeliveries(2)
						.redeliveryDelay(1000).retryAttemptedLogLevel(LoggingLevel.ERROR)
						.logStackTrace(false));
				from("seda:queue.inbox").log("Received input ${body}")
						.bean("orderService", "validate").bean("orderService", "enrich")
						.log("Received order ${body}").to("mock:queue.order");
			}
		});
		context.start();

		// notice that the order is preserved when we use sync redelivery
		// only the second bood will pass
		MockEndpoint endpoint = getMockEndpoint("mock:queue.order");
		endpoint.expectedBodiesReceived("amount=1,name=Camel in Action,id=123,status=OK");

		template.sendBody("seda:queue.inbox", "amount=1,name=ActiveMQ in Action");
		template.sendBody("seda:queue.inbox", "amount=1,name=Camel in Action");

		assertMockEndpointsSatisfied();
	}

	@Test
	public void testAsyncOrderFailThenOK() throws Exception {
		context.addRoutes(new RouteBuilder() {

			@Override
			public void configure() throws Exception {
				errorHandler(deadLetterChannel("mock:dead").asyncDelayedRedelivery()
						.maximumRedeliveries(2).redeliveryDelay(1000)
						.retryAttemptedLogLevel(LoggingLevel.ERROR).logStackTrace(false));
				from("seda:queue.inbox").log("Received input ${body}")
						.bean("orderService", "validate").bean("orderService", "enrich")
						.log("Received order ${body}").to("mock:queue.order");
			}
		});
		context.start();

		MockEndpoint endpoint = getMockEndpoint("mock:queue.order");
		endpoint.expectedBodiesReceived("amount=1,name=Camel in Action,id=123,status=OK");

		MockEndpoint mockEndpoint = getMockEndpoint("mock:dead");
		mockEndpoint.expectedMessageCount(1);
		mockEndpoint.message(0).body().contains("ActiveMQ");

		template.sendBody("seda:queue.inbox", "amount=1,name=ActiveMQ in Action");
		template.sendBody("seda:queue.inbox", "amount=1,name=Camel in Action");

		assertMockEndpointsSatisfied();
	}
}
